package com.e_manager.soft.emanager.authorFilter;

import com.alibaba.fastjson.JSON;
import com.e_manager.soft.emanager.annotation.Authorization;
import com.e_manager.soft.emanager.resultMsg.ResultConstant;
import com.e_manager.soft.emanager.resultMsg.ResultInfo;
import com.e_manager.soft.emanager.service.TokenManager;
import com.e_manager.soft.emanager.token.TokenConstant;
import com.e_manager.soft.emanager.token.TokenModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;

/**
 * 自定义拦截器，判断此次请求是否有权限
 *
 * @author jys
 * @see
 */
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private TokenManager manager;


    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) {
        try {
            ResultInfo resultInfo = new ResultInfo();
            //如果不是映射到方法直接通过
            if (!(handler instanceof HandlerMethod)) {
                return true;
            }
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            handler.getClass().getAnnotation(Authorization.class);
            //如果没有@Authorization 注解，直接通过
            if (handlerMethod.getBeanType().getAnnotation(Authorization.class) == null
                    && method.getAnnotation(Authorization.class) == null) {
                return true;
            }
            //从header中得到token
            String authorization = request.getHeader(TokenConstant.AUTHORIZATION);
            //如果验证token失败，并且方法注明了Authorization，返回401错误
            if (authorization == null || "".equals(authorization)) {
                resultInfo.setCode(ResultConstant.UN_AUTHORIZED.getCode());
                resultInfo.setMsg("用户授权认证没有通过!客户端请求参数中无token信息");
                result(resultInfo, response);
                return false;
            }
            //验证token
            TokenModel model = manager.getToken(authorization);
            if (manager.checkToken(model)) {
                //如果token验证成功，将token对应的用户id存在request中，便于之后注入
                request.setAttribute(TokenConstant.CURRENT_USER_ID, model.getUserId());
                return true;
            } else {
                resultInfo.setCode(ResultConstant.UN_AUTHORIZED.getCode());
                resultInfo.setMsg("用户授权认证没有通过!客户端请求参数token信息无效");
                result(resultInfo, response);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    private void result(ResultInfo resultInfo, HttpServletResponse response) throws IOException {
        PrintWriter writer = null;
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(response.getOutputStream(),
                    "UTF-8");
            writer = new PrintWriter(osw, true);
            String jsonStr = JSON.toJSONString(resultInfo);
            writer.write(jsonStr);
            writer.flush();
            writer.close();
            osw.close();
        } catch (UnsupportedEncodingException e) {
            e.getMessage();
        } catch (IOException e) {
            e.getMessage();
        } finally {
            if (null != writer) {
                writer.close();
            }
            if (null != osw) {
                osw.close();
            }
        }
    }
}
